package com.ecoolex.ying.space.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.CollectorUtil;
import com.ecoolex.ying.space.core.dao.DesignerProjectItemsProductDAO;
import com.ecoolex.ying.space.entity.*;
import com.ecoolex.ying.space.pojo.DesignerProjectItemsPickProductDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.IntStream;

import static com.ecoolex.ying.space.entity.DesignerProjectItemsProduct.*;

@Service
public class DesignerProjectItemsProductManager {
    @Autowired
    private DesignerProjectItemsProductDAO dao;
    @Autowired
    private DesignerProjectItemsProductCustomManager designerProjectItemsProductCustomManager;
    @Autowired
    private PickGoodsProductManager pickGoodsProductManager;

    private void verify(DesignerProjectItemsPickProductDTO[] pickProducts) {
        for (DesignerProjectItemsPickProductDTO item : pickProducts) {
            BizAssert.isTrue(Check.notNull(item.getPickProductId()), ResultCode.VERIFY.build(50), "PickProductId不存在");
            BizAssert.isTrue(Check.notNullAndGtZero(item.getNumber()) && item.getNumber() < 999 + 1, ResultCode.VERIFY.build(51), "number不能为空并且小于等于999");
        }
        // 重复检查
//        long distinctCount = Arrays.stream(pickProducts).mapToInt(DesignerProjectItemsPickProductDTO::getPickProductId).distinct().count();
//        BizAssert.isTrue(distinctCount == pickProducts.length, ResultCode.VERIFY.build(52), "PickProductId存在重复数据");
    }

    void update(DesignerProject project, Integer itemsId, DesignerProjectItemsPickProductDTO[] pickProducts, String updateUser) {
        // 检查null
        DesignerProjectItemsPickProductDTO[] pickProductList = Check.isNull(pickProducts) ? new DesignerProjectItemsPickProductDTO[0] : pickProducts;
        // 参数检查
        verify(pickProductList);
        // 已经存在的
        List<DesignerProjectItemsProduct> oldList = queryByItemsId(itemsId);

        IntStream.range(0, pickProductList.length).forEach(i -> {
            DesignerProjectItemsPickProductDTO edit = pickProductList[i];
            DesignerProjectItemsProduct old = oldList.stream().collect(CollectorUtil.first(o -> edit.getPickProductId().equals(o.getPickProductId())));
            if (Check.isNull(old)) {
                // 创建
                create(project, itemsId, edit, i + 1, updateUser);
            } else {
                // 判断是否需要修改
                if (!old.getNumber().equals(edit.getNumber()) || !old.getSorting().equals(i + 1)) {
                    update(old, updateUser);
                }
                oldList.remove(old);
            }
        });

        // 删除没用的
        oldList.forEach(record -> {
            delete(record.getItemsProductId(), updateUser);
            designerProjectItemsProductCustomManager.deleteByItemsProductId(record.getItemsProductId(), updateUser);
        });
    }

    void copy(Integer sourceItemId, DesignerProjectItems targetItem, String createUser) {
        queryByItemsId(sourceItemId).forEach(itemsProduct -> {
            Integer sourceItemsProductId = itemsProduct.getItemsProductId();

            itemsProduct.setProjectId(targetItem.getProjectId());
            itemsProduct.setItemsId(targetItem.getItemsId());
            itemsProduct.setCreateUser(createUser);
            itemsProduct.setCreateTime(Date.from(Instant.now()));
            itemsProduct.setUpdateUser(createUser);
            itemsProduct.setUpdateTime(Date.from(Instant.now()));
            dao.insert(itemsProduct);

            designerProjectItemsProductCustomManager.copy(sourceItemsProductId, itemsProduct, createUser);
        });
    }

    private void create(DesignerProject project, Integer itemsId, DesignerProjectItemsPickProductDTO edit, Integer sorting, String createUser) {
        PickGoodsProduct product = pickGoodsProductManager.getById(edit.getPickProductId());
        BizAssert.isTrue(Check.notNull(product), ResultCode.VERIFY.build(59), "优选产品不存在");

        DesignerProjectItemsProduct record = new DesignerProjectItemsProduct();
        record.setUserId(project.getUserId());
        record.setProjectId(project.getProjectId());
        record.setItemsId(itemsId);
        record.setPickGoodsId(product.getPickGoodsId());
        record.setPickProductId(product.getPickProductId());
        record.setNumber(edit.getNumber());
        record.setSorting(sorting);
        record.setDeleted(NOT_DELETED);
        record.setCreateUser(createUser);
        record.setCreateTime(Date.from(Instant.now()));
        record.setUpdateUser(createUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.insert(record);

        designerProjectItemsProductCustomManager.create(record, createUser);
    }

    private void update(DesignerProjectItemsProduct record, String updateUser) {
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        dao.updateByPrimaryKeySelective(record,
                Column.number,
                Column.sorting,
                Column.updateUser,
                Column.updateTime);
    }

    private void delete(Integer itemsProductId, String updateUser) {
        DesignerProjectItemsProduct record = new DesignerProjectItemsProduct();
        record.setDeleted(IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        DesignerProjectItemsProductExample example = new DesignerProjectItemsProductExample();
        example.createCriteria()
                .andItemsProductIdEqualTo(itemsProductId)
                .andDeletedEqualTo(NOT_DELETED);

        dao.updateByExampleSelective(record,
                example,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    void deleteByItemsId(DesignerProject project, Integer itemsId, String updateUser) {
        DesignerProjectItemsProduct record = new DesignerProjectItemsProduct();
        record.setDeleted(IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        DesignerProjectItemsProductExample example = new DesignerProjectItemsProductExample();
        example.createCriteria()
                .andItemsIdEqualTo(itemsId)
                .andDeletedEqualTo(NOT_DELETED);

        dao.updateByExampleSelective(record,
                example,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    void deleteByPickProductId(Integer pickProductId, String updateUser) {
        DesignerProjectItemsProduct record = new DesignerProjectItemsProduct();
        record.setDeleted(IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        DesignerProjectItemsProductExample example = new DesignerProjectItemsProductExample();
        example.createCriteria()
                .andPickProductIdEqualTo(pickProductId)
                .andDeletedEqualTo(NOT_DELETED);

        dao.updateByExampleSelective(record,
                example,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    void deleteByPickGoodsId(Integer pickGoodsId, String updateUser) {
        DesignerProjectItemsProduct record = new DesignerProjectItemsProduct();
        record.setDeleted(IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        DesignerProjectItemsProductExample example = new DesignerProjectItemsProductExample();
        example.createCriteria()
                .andPickGoodsIdEqualTo(pickGoodsId)
                .andDeletedEqualTo(NOT_DELETED);

        dao.updateByExampleSelective(record,
                example,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    void deleteByProjectId(Integer projectId, String updateUser) {
        DesignerProjectItemsProduct record = new DesignerProjectItemsProduct();
        record.setDeleted(IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        DesignerProjectItemsProductExample example = new DesignerProjectItemsProductExample();
        example.createCriteria()
                .andProjectIdEqualTo(projectId)
                .andDeletedEqualTo(NOT_DELETED);

        dao.updateByExampleSelective(record,
                example,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    public List<DesignerProjectItemsProduct> queryByItemsId(Integer itemsId) {
        DesignerProjectItemsProductExample example = new DesignerProjectItemsProductExample();
        example.createCriteria()
                .andItemsIdEqualTo(itemsId)
                .andDeletedEqualTo(NOT_DELETED);
        example.orderBy(Column.sorting.asc());
        return dao.selectByExample(example);
    }
}